﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;

public class EnemyMgr
{
	public event Action OnEnemeyClear;

	#region Field
	private const int MaxCountLimit = 3;
	private int MaxEnemyCount = 0;
	private int HasSpawnCount = 0;

	private List<EnemyCtrl> enemyList = new List<EnemyCtrl>(); 

	#endregion

	#region Attribute
	public event Action<int> OnEnemeyCountChange;
	private int _curEnemyCount = 0;
	/// <summary>
	/// 当前场景内敌人数量
	/// </summary>
	public int CurEnemyCount {
		get { return _curEnemyCount; }
		set {
			value = Mathf.Max(0, value);
			if (_curEnemyCount != value)
			{
				_curEnemyCount = value;
				if (OnEnemeyCountChange != null)
				{
					OnEnemeyCountChange(_curEnemyCount);
				}
			}
		}
	}
	#endregion

	GameObjectPool enemyGoPool = new GameObjectPool();

	public GameObject enemy1;

	public void Init()
	{
		enemy1 = Resources.Load<GameObject>("Enemy/Prefabs/Enemy1");
	}

	public void GenerateEnemies(int maxEnemyCount)
	{
		MaxEnemyCount = maxEnemyCount;
		int count = MaxCountLimit;
		while (count > 0) {
			GenerateEnemy();
			count--;
		}
	}

	private void GenerateEnemy()
	{
		if (HasSpawnCount < MaxEnemyCount)
		{
			GameObject go = enemyGoPool.GetObject();
			EnemyInfo info = MainGame.Ins.CurLevelInfo.EnemyList[CurEnemyCount];

			if (!go)
			{
				go = Object.Instantiate(MainGame.EnemyMgr.enemy1);
				go.transform.SetParent(GameObject.FindWithTag("Root").transform);
			}
			go.transform.position = MainGame.AStarGridMgr.ChooseSpawnPos();
			EnemyCtrl ctrl = go.TryGetComponent<EnemyCtrl>();
			ctrl.OnDie += EnemyDie;
			ctrl.Init(info);
			enemyList.Add(ctrl);

			HasSpawnCount++;
			CurEnemyCount++;
		}
	}

	private void EnemyDie(EnemyCtrl ctrl)
	{
		CurEnemyCount--;
		ctrl.OnDie -= EnemyDie;
		if (CurEnemyCount <= 0) {
			if (OnEnemeyClear != null) {
				OnEnemeyClear();
			}
		}

		MonoHelper.Ins.StartCoroutine(DelayToDo(3, () =>
		{
			GenerateEnemy();
			enemyGoPool.ReturnObject(ctrl.gameObject);
		}));
	}

	private IEnumerator DelayToDo(float delay, Action act) {
		yield return new WaitForSeconds(delay);

		if (act != null) {
			act();
		}
	}

	public void Reset()
	{
		HasSpawnCount = 0;
		CurEnemyCount = 0;

		for (int i = 0, length = enemyList.Count; i < length; i++) {
			EnemyCtrl enemy = enemyList[i];
			enemy.Clear();
			enemyGoPool.ReturnObject(enemy.gameObject);
		}

		enemyList.Clear();
	}

	public void Clear()
	{
		HasSpawnCount = 0;
		CurEnemyCount = 0;

		enemyGoPool.Clear();
	}
}
